package io.github.cameradddd.dao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.io.File;

import io.github.cameradddd.entity.AccountRecord;

/**
 * 这是一个与data直接交互的DAO类
 */
public class AccountDAO {

    private final static String DATAPATH = "src/main/resources/data/data.csv";

    /**
     * 保存record对象到data.csv
     * 
     * @param record
     */
    public static void save(AccountRecord record) {
        try (BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(DATAPATH, true), "UTF-8"))) {
            bw.append(record.toString());
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    /**
     * 获取所有Record对象
     * 
     * @return 一个存储了所有Record对象的表
     */
    public static List<AccountRecord> findAll() {
        List<AccountRecord> recordList = new ArrayList<>();
        String line;
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(DATAPATH), "UTF-8"))) {
            // 丢弃表头
            @SuppressWarnings("unused")
            String header = br.readLine();

            // 逐行读取文件内容
            while ((line = br.readLine()) != null) {
                String[] data = line.split(",");
                if (data.length >= 5) {
                    String id=data[0];
                    String date = data[1];
                    String type = data[2];
                    String amount = data[3];
                    String remark = data[4];
                    // new一个AccountRecord,添加到List中
                    recordList.add(
                            new AccountRecord(
                                    Integer.parseInt(id),
                                    LocalDateTime.parse(date),
                                    (type.equals("收入")) ? true : false,
                                    Double.parseDouble(amount),
                                    remark));
                } else {
                    //TODO
                    System.out.println("文件格式错误222"+recordList.toString());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return recordList;
    }

    /**
     * 获取record的总数目
     * @return
     */
    public static int getRecordNumber() {
        int count = 0;
        try (Scanner reader = new Scanner(new File(DATAPATH))) {
            while (reader.hasNextLine()) {
                reader.nextLine();
                count++;
            }
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        return count;
    }

    /**
     * 计算总金额
     * 
     * @return 总金额
     */
    public static double calculateAmount() {
        return findAll().stream()
                .mapToDouble(record -> record.isIncome() ? record.getAmount() : -record.getAmount())
                .sum();
    }

    /**
     * 删除记录,默认删除最近的
     */
    public static boolean deleteRecord() {
        List<AccountRecord> records = findAll();
        if (records.isEmpty()) {
            System.out.print("没有记录可删除");
            return false;
        }

        // 默认删除最近的记录（最后一条）
        records.remove(records.size() - 1);

        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("日期,类型,金额,备注");
            bw.newLine();
            // 写入剩余记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("删除记录时发生异常");
            return false;
        }
        return true;
    }

    /**
     * 删除指定账目
     * 
     * @param hashCode
     * @return
     */
    public static boolean deleteRecord(int id) {
        List<AccountRecord> records = findAll();
        if (records.isEmpty()) {
            System.out.print("没有记录可删除");
            return false;
        }

        // 删除指定的记录
        boolean removed = records.removeIf(record -> record.getId() == id);
        if (!removed) {
            System.out.print("未找到指定的记录");
            return false;
        }

        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("日期,类型,金额,备注");
            bw.newLine();
            // 写入剩余记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("删除记录时发生异常");
            return false;
        }
        return true;
    }

    /**
     * 批量删除账目
     * @param idList
     * @return
     */
    public static boolean deleteRecord(List<Integer> idList) {
        List<AccountRecord> records = findAll();
        if (records.isEmpty()) {
            System.out.print("没有记录可删除");
            return false;
        }
        // 根据id表删除records中的账目
        boolean removed = records.removeIf(record -> idList.contains(record.getId()));
        if (!removed) {
            System.err.print("未找到指定的记录");
            return false;
        }

        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("id,日期,类型,金额,备注");
            bw.newLine();
            // 写入剩余记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("删除记录时发生异常");
            return false;
        }
        return true;
    }

    /**
     * 修改账目信息
     * @param id
     * @param newAmount
     * @param newRemark
     * @return
     */
    public static boolean editRecord(int id, double newAmount, String newRemark) {
        List<AccountRecord> records = findAll();
        boolean found = false;
        for (AccountRecord record : records) {
            if (record.getId() == id) {
                record.setAmount(newAmount);
                record.setRemark(newRemark);
                found = true;
                break;
            }
        }
        if (!found) {
            System.out.print("未找到指定的记录");
            return false;
        }
        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("日期,类型,金额,备注");
            bw.newLine();
            // 写入所有记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("修改记录时发生异常");
            return false;
        }
        return true;
    }
    /**
     * 修改账目信息,只有id,和newAmount两个参数的重载
     * @param hid
     * @param newAmount
     * @return
     */
    public static boolean editRecord(int id, double newAmount) {
        List<AccountRecord> records = findAll();
        boolean found = false;
        for (AccountRecord record : records) {
            if (record.getId() == id) {
                record.setAmount(newAmount);
                found = true;
                break;
            }
        }
        if (!found) {
            System.err.print("未找到指定的记录");
            return false;
        }
        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("日期,类型,金额,备注");
            bw.newLine();
            // 写入所有记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("修改记录时发生异常");
            return false;
        }
        return true;
    }

        /**
     * 修改账目信息,只有id,和newRemark两个参数的重载
     * @param hid
     * @param newAmount
     * @return
     */
    public static boolean editRecord(int id, String newRemark) {
        List<AccountRecord> records = findAll();
        boolean found = false;
        for (AccountRecord record : records) {
            if (record.getId() == id) {
                record.setRemark(newRemark);
                found = true;
                break;
            }
        }
        if (!found) {
            System.out.print("未找到指定的记录");
            return false;
        }
        // 重新写入文件
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(DATAPATH), "UTF-8"))) {
            // 写入表头
            bw.write("日期,类型,金额,备注");
            bw.newLine();
            // 写入所有记录
            for (AccountRecord record : records) {
                bw.write(record.toString());
            }
        } catch (IOException e) {
            System.out.print("修改记录时发生异常");
            return false;
        }
        return true;
    }

    /**
     * 为新record分配id
     * @return
     */
    // 为新record分配id，避免线程安全问题
    public synchronized static int newId() {
        List<AccountRecord> records = findAll();
        if (records.isEmpty()) {
            return 0;
        }
        int lastId = records.stream().mapToInt(AccountRecord::getId).max().orElse(0);
        return lastId + 1;
    }
}
